home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / spatial / disp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  12.9 KB  |  466 lines

  1. /* (C) Copyright 1991 Andrew Plotkin. Permission is
  2.  given to copy and use, as long as this copyright
  3.  notice is retained. */
  4.  
  5. #include <stdio.h>
  6. #include <X11/Xlib.h>
  7. #include <X11/Xutil.h>
  8. #include "spatial.h"
  9. #include "grey01.bm"
  10. #include "grey02.bm"
  11. #include "grey03.bm"
  12. #include "grey04.bm"
  13. #include "grey05.bm"
  14. #include "grey06.bm"
  15. #include "grey07.bm"
  16. #include "grey08.bm"
  17. #include "grey09.bm"
  18. #include "grey10.bm"
  19. #include "grey11.bm"
  20. #include "grey12.bm"
  21. #include "grey13.bm"
  22. #include "grey14.bm"
  23. #include "grey15.bm"
  24. #include "grey16.bm"
  25.  
  26. Display *dpy;
  27. Window win;
  28. Pixmap backpm, fieldpm;
  29. GC gcblack, gcwhite, gcinv, gccopy, gcline,
  30. gcfield, gccubes[16]; /* graphics contexts */
  31. int scn;
  32. int scndepth;
  33. int forcemono = 0;
  34.  
  35. piecelist pieces[MAXPIECES];
  36.  
  37. short numpieces;
  38. short curpiece;
  39.  
  40. int dispx, dispy; /* size of window */
  41. int shapex1, shapex2, shapey1, shapey2;
  42. /* coords of rectangle of backpm that is different from fieldpm */
  43. int ddispx1, ddispx2, ddispy1, ddispy2;
  44. /* coords of rectangle of display that is different from fieldpm */
  45.  
  46. extern void dumppiece(), setup_fieldpm(),
  47. setup_one_fieldpm(), draw_curpiece();
  48.  
  49. void xinit() /* using dispx, dispy */
  50. {
  51.     register int ix;
  52.     XSetWindowAttributes attr;
  53.     XGCValues gcvalues;
  54.     static char dashes[2] = {1, 1};
  55.     Pixmap greypm[16];
  56.     XSizeHints hints;
  57.     Status res;
  58.     XColor col, sccol;
  59.     static unsigned short colvalues[16][3] = {
  60.     {0x0000, 0x0000, 0x0000},
  61.     {0x6000, 0xA000, 0x6000}, /* green grey */
  62.     {0x0000, 0x0000, 0x0000},
  63.     {0x6000, 0x6000, 0xA000}, /* blue grey */
  64.     {0xC000, 0x0000, 0x0000}, /* red */
  65.     {0x0000, 0x0000, 0x0000},
  66.     {0x0000, 0x0000, 0x0000},
  67.     {0xAA00, 0x8000, 0x0000}, /* orange */
  68.     {0x0000, 0x0000, 0x0000},
  69.     {0xC000, 0xC000, 0x0000}, /* yellow */
  70.     {0x0000, 0xC000, 0x0000}, /* green */
  71.     {0x0000, 0x0000, 0xFF00}, /* blue */
  72.     {0x8000, 0x0000, 0xC000}, /* purple */
  73.     {0xFF00, 0x6000, 0x6000}, /* light red */
  74.     {0x8000, 0x8000, 0xFF00}, /* light blue */
  75.     {0xC000, 0xC000, 0xC000}  /* light grey */
  76.     };
  77.  
  78.     dpy = XOpenDisplay((char *) NULL);
  79.     if ((Display *) NULL == dpy) {
  80.     fprintf(stderr, "spatial: could not open display.\n");
  81.     exit(-1);
  82.     }
  83.  
  84.     scn = DefaultScreen(dpy);
  85.     scndepth = DefaultDepth(dpy, scn);
  86.  
  87.     win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy),
  88.     100, 100, dispx, dispy, 1, BlackPixel(dpy, scn),
  89.     WhitePixel(dpy, scn));
  90.  
  91.     hints.min_width = 100;
  92.     hints.min_height = 100;
  93.     hints.width = dispx;
  94.     hints.height = dispy;
  95.     hints.flags = PMinSize | PSize;
  96.     XSetWMNormalHints(dpy, win, &hints);
  97.  
  98.     XStoreName(dpy, win, "Spatial");
  99.  
  100.     attr.event_mask = (KeyPressMask | ExposureMask | StructureNotifyMask);
  101.     XChangeWindowAttributes(dpy, win, CWEventMask, &attr);
  102.  
  103.     XSetWindowBackground(dpy, win, BlackPixel(dpy, scn));
  104.  
  105.     XMapWindow(dpy, win);
  106.  
  107.     gcvalues.foreground = WhitePixel(dpy, scn);
  108.     gcvalues.background = BlackPixel(dpy, scn);
  109.     gcwhite = XCreateGC(dpy, win, GCForeground|GCBackground,
  110.     &gcvalues);
  111.  
  112.     if (forcemono || DefaultDepth(dpy, scn)==1) {
  113.  
  114.     greypm[0] = XCreatePixmapFromBitmapData(dpy, win,
  115.     grey01_bits, grey01_width, grey01_height, 0, 1, 1);
  116.     greypm[1] = XCreatePixmapFromBitmapData(dpy, win,
  117.     grey02_bits, grey02_width, grey02_height, 0, 1, 1);
  118.     greypm[2] = XCreatePixmapFromBitmapData(dpy, win,
  119.     grey03_bits, grey03_width, grey03_height, 0, 1, 1);
  120.     greypm[3] = XCreatePixmapFromBitmapData(dpy, win,
  121.     grey04_bits, grey04_width, grey04_height, 0, 1, 1);
  122.     greypm[4] = XCreatePixmapFromBitmapData(dpy, win,
  123.     grey05_bits, grey05_width, grey05_height, 0, 1, 1);
  124.     greypm[5] = XCreatePixmapFromBitmapData(dpy, win,
  125.     grey06_bits, grey06_width, grey06_height, 0, 1, 1);
  126.     greypm[6] = XCreatePixmapFromBitmapData(dpy, win,
  127.     grey07_bits, grey07_width, grey07_height, 0, 1, 1);
  128.     greypm[7] = XCreatePixmapFromBitmapData(dpy, win,
  129.     grey08_bits, grey08_width, grey08_height, 0, 1, 1);
  130.     greypm[8] = XCreatePixmapFromBitmapData(dpy, win,
  131.     grey09_bits, grey09_width, grey09_height, 0, 1, 1);
  132.     greypm[9] = XCreatePixmapFromBitmapData(dpy, win,
  133.     grey10_bits, grey10_width, grey10_height, 0, 1, 1);
  134.     greypm[10] = XCreatePixmapFromBitmapData(dpy, win,
  135.      grey11_bits, grey11_width, grey11_height, 0, 1, 1);
  136.     greypm[11] = XCreatePixmapFromBitmapData(dpy, win,
  137.      grey12_bits, grey12_width, grey12_height, 0, 1, 1);
  138.     greypm[12] = XCreatePixmapFromBitmapData(dpy, win,
  139.      grey13_bits, grey13_width, grey13_height, 0, 1, 1);
  140.     greypm[13] = XCreatePixmapFromBitmapData(dpy, win,
  141.      grey14_bits, grey14_width, grey14_height, 0, 1, 1);
  142.     greypm[14] = XCreatePixmapFromBitmapData(dpy, win,
  143.      grey15_bits, grey15_width, grey15_height, 0, 1, 1);
  144.     greypm[15] = XCreatePixmapFromBitmapData(dpy, win,
  145.      grey16_bits, grey16_width, grey16_height, 0, 1, 1);
  146.  
  147.     gcvalues.fill_style = FillOpaqueStippled;
  148.     for (ix=0; ix<16; ix++) {
  149.         gcvalues.stipple = greypm[ix];
  150.         gccubes[ix] = XCreateGC(dpy, win,
  151.         GCForeground|GCBackground|GCFillStyle|GCStipple,
  152.         &gcvalues);
  153.     };
  154.     }
  155.     else {
  156.     for (ix=0; ix<16; ix++) {
  157.         col.red = colvalues[ix][0];
  158.         col.green = colvalues[ix][1];
  159.         col.blue = colvalues[ix][2];
  160.         res = XAllocColor(dpy, DefaultColormap(dpy, scn),
  161.         &col);
  162.         if (!res) {
  163.         fprintf(stderr, "spatial: unable to allocate colors\n");
  164.         exit(-1);
  165.         }
  166.         gcvalues.foreground = col.pixel;
  167.         gccubes[ix] = XCreateGC(dpy, win, GCForeground,
  168.         &gcvalues);
  169.     }
  170.  
  171.     }
  172.  
  173.     gcvalues.foreground = WhitePixel(dpy, scn);
  174.     gcvalues.background = BlackPixel(dpy, scn);
  175.  
  176.     gcvalues.line_style = LineOnOffDash;
  177.     gcfield = XCreateGC(dpy, win, GCForeground|GCLineStyle,
  178.     &gcvalues);
  179.  
  180.     XSetDashes(dpy, gcfield, 0, dashes, 2);
  181.     gcvalues.line_width = 2;
  182.     gcline = XCreateGC(dpy, win, GCForeground|GCLineWidth,
  183.     &gcvalues);
  184.  
  185.     gcvalues.foreground = BlackPixel(dpy, scn);
  186.     gcblack = XCreateGC(dpy, win, GCForeground, &gcvalues);
  187.  
  188.     gcvalues.function = GXinvert;
  189.     gcinv = XCreateGC(dpy, win, GCForeground|GCFunction, &gcvalues);
  190.  
  191.     gcvalues.background = WhitePixel(dpy, scn);
  192.     gccopy = XCreateGC(dpy, win, GCForeground|GCBackground, &gcvalues);
  193.     XSetGraphicsExposures(dpy, gccopy, 0);
  194.  
  195.     backpm = XCreatePixmap(dpy, win, dispx, dispy, scndepth);   
  196.     fieldpm = XCreatePixmap(dpy, win, dispx, dispy, scndepth);   
  197. }
  198.  
  199. void setup_fieldpm() /* clear, draw field box and side
  200.  text. Also set shape{x,y}{1,2} to window size */
  201. {
  202.     XFillRectangle(dpy, fieldpm, gcblack, 0, 0, dispx, dispy);
  203.     XDrawImageString(dpy, fieldpm, gcwhite, 50,
  204.     (int)boardscale+20, "Score: ", 7); 
  205.  
  206.     setup_one_fieldpm(fieldpts);
  207.     if (stereo)
  208.     setup_one_fieldpm(fieldpts2);
  209.  
  210.     shapex1 = 0;
  211.     shapex2 = dispx-1;
  212.     shapey1 = 0;
  213.     shapey2 = dispy-1;
  214.     ddispx1 = 0;
  215.     ddispx2 = dispx-1;
  216.     ddispy1 = 0;
  217.     ddispy2 = dispy-1;
  218.     meteroldlev = 0;
  219. }
  220.  
  221. void setup_one_fieldpm(fips)
  222. fieldplist fips;
  223. {
  224.     register int ix, iy, iz;
  225.  
  226.     for (iz=0; iz<=fieldz; iz++) {
  227.     XDrawLine(dpy, fieldpm, gcfield, fips[0][0][iz].x,
  228.           fips[0][0][iz].y, fips[fieldx][0][iz].x,
  229.           fips[fieldx][0][iz].y);
  230.     XDrawLine(dpy, fieldpm, gcfield,
  231.           fips[fieldx][fieldy][iz].x, fips[fieldx][fieldy][iz].y,
  232.           fips[fieldx][0][iz].x, fips[fieldx][0][iz].y);
  233.     XDrawLine(dpy, fieldpm, gcfield, fips[0][0][iz].x,
  234.           fips[0][0][iz].y, fips[0][fieldy][iz].x, fips[0][fieldy][iz].y);
  235.     XDrawLine(dpy, fieldpm, gcfield,
  236.           fips[fieldx][fieldy][iz].x, fips[fieldx][fieldy][iz].y,
  237.           fips[0][fieldy][iz].x, fips[0][fieldy][iz].y);
  238.     };
  239.     for (ix=0; ix<=fieldx; ix++) {
  240.     XDrawLine(dpy, fieldpm, gcfield, fips[ix][0][0].x,
  241.           fips[ix][0][0].y, fips[ix][0][fieldz].x,
  242.           fips[ix][0][fieldz].y);
  243.     XDrawLine(dpy, fieldpm, gcfield, fips[ix][0][0].x,
  244.           fips[ix][0][0].y, fips[ix][fieldy][0].x, fips[ix][fieldy][0].y);
  245.     XDrawLine(dpy, fieldpm, gcfield,
  246.           fips[ix][fieldy][fieldz].x, fips[ix][fieldy][fieldz].y,
  247.           fips[ix][fieldy][0].x, fips[ix][fieldy][0].y);
  248.     }
  249.     for (iy=1; iy<fieldy; iy++) {
  250.     XDrawLine(dpy, fieldpm, gcfield, fips[0][iy][0].x,
  251.           fips[0][iy][0].y, fips[0][iy][fieldz].x,
  252.           fips[0][iy][fieldz].y);
  253.     XDrawLine(dpy, fieldpm, gcfield, fips[fieldx][iy][0].x,
  254.           fips[fieldx][iy][0].y, fips[0][iy][0].x,
  255.           fips[0][iy][0].y);
  256.     XDrawLine(dpy, fieldpm, gcfield, fips[fieldx][iy][0].x,
  257.           fips[fieldx][iy][0].y, fips[fieldx][iy][fieldz].x,
  258.           fips[fieldx][iy][fieldz].y);
  259.     };
  260. }
  261.  
  262. void draw_score(drw)
  263. Drawable drw;
  264. {
  265.     static char buf[32];
  266.     register int ix;
  267.     long sc;
  268.  
  269.     if (score==0) {
  270.     XDrawImageString(dpy, drw, gcwhite, 106,
  271.              (int)boardscale+20, "0         ", 10);
  272.     }
  273.     else {
  274.     sc = score;
  275.     ix = 32;
  276.     buf[--ix] = '\0';
  277.     while (sc) {
  278.         buf[--ix] = (sc%10) + '0';
  279.         sc /= 10;
  280.     };
  281.     XDrawImageString(dpy, drw, gcwhite, 106,
  282.              (int)boardscale+20, buf+ix, 31-ix);
  283.     }
  284. }
  285.  
  286. void update_meter() /* on fieldpm */
  287. {
  288.     register int ix;
  289.     int x1, y1, width, heigh;
  290.     GC *gcc;
  291.  
  292.     if (meterlev > meteroldlev) {
  293.     for (ix=meteroldlev; ix<meterlev; ix++) {
  294.         gcc = &(gccubes[colors[ix]]);
  295.         x1 = meterx + metersize*ix;
  296.         y1 = metery;
  297.         width = metersize-1;
  298.         heigh = 20;
  299.         XFillRectangle(dpy, fieldpm, *gcc, x1, y1, width, heigh);
  300.         XDrawRectangle(dpy, fieldpm, gcwhite, x1, y1,
  301.                width, heigh);
  302.         if (stereo) {
  303.         x1 = meterx2 + metersize*ix;
  304.         XFillRectangle(dpy, fieldpm, *gcc, x1, y1,
  305.                    width, heigh);
  306.         XDrawRectangle(dpy, fieldpm, gcwhite, x1, y1,
  307.                    width, heigh);
  308.         }
  309.     }
  310.     }
  311.     else {
  312.     x1 = meterx + metersize*meterlev + 1;
  313.     y1 = metery;
  314.     width = (meteroldlev - meterlev) * metersize;
  315.     heigh = 20;
  316.     XFillRectangle(dpy, fieldpm, gcblack, x1, y1, width, heigh);
  317.     if (stereo) {
  318.         x1 = meterx2 + metersize*meterlev + 1;
  319.         XFillRectangle(dpy, fieldpm, gcblack, x1, y1,
  320.                width, heigh);
  321.     }
  322.     }
  323.     meteroldlev = meterlev;
  324.     meter_f_b = 1;
  325. }
  326.  
  327. void setup_backpm() 
  328. {
  329.     XCopyArea(dpy, fieldpm, backpm, gccopy, shapex1, shapey1,
  330.           shapex2-shapex1+1, shapey2-shapey1+1, shapex1, shapey1);
  331.     
  332.     if (shapey2 > (int)boardscale && shapex1 < 300) {
  333.     draw_score(backpm);
  334.     }
  335.  
  336.     if (meter_f_b) {
  337.     XCopyArea(dpy, fieldpm, backpm, gccopy, meterx,
  338.           metery, metersize*fieldz+1, 21, meterx, metery);
  339.     if (stereo) {
  340.         XCopyArea(dpy, fieldpm, backpm, gccopy, meterx2,
  341.               metery, metersize*fieldz+1, 21, meterx2, metery);
  342.     }
  343.     meter_f_b = 0;
  344.     meter_b_d = 1;
  345.     }
  346.  
  347.     if (curpiece != (-1)) {
  348.     /* draw current piece on backpm, storing
  349.      shape{x,y}{1,2} limits */
  350.     draw_curpiece(backpm);
  351.     }
  352. }
  353.  
  354. void back_to_disp(all)
  355. int all; 
  356. {
  357.     if (all) {
  358.     XCopyArea(dpy, backpm, win, gccopy, 0, 0,
  359.           dispx, dispy, 0, 0);
  360.     }
  361.     else {
  362.     /* copy from backpm to display; area is
  363.      max{shape, ddisp}; */
  364.     if (ddispx1 > shapex1) ddispx1 = shapex1;
  365.     if (ddispy1 > shapey1) ddispy1 = shapey1;
  366.     if (ddispx2 < shapex2) ddispx2 = shapex2;
  367.     if (ddispy2 < shapey2) ddispy2 = shapey2;
  368.     XCopyArea(dpy, backpm, win, gccopy, ddispx1, ddispy1,
  369.           ddispx2-ddispx1+1, ddispy2-ddispy1+1, ddispx1, ddispy1);
  370.  
  371.     if (meter_b_d) {
  372.         XCopyArea(dpy, backpm, win, gccopy, meterx, metery,
  373.               metersize*fieldz+1, 21, meterx, metery);
  374.         if (stereo) {
  375.         XCopyArea(dpy, backpm, win, gccopy, meterx2,
  376.               metery, metersize*fieldz+1, 21, meterx2, metery);
  377.         }
  378.         meter_b_d = 0;
  379.     }
  380.  
  381.     /* set ddisp limits to shape limits; */
  382.     ddispx1 = shapex1;
  383.     ddispy1 = shapey1;
  384.     ddispx2 = shapex2;
  385.     ddispy2 = shapey2;
  386.     }
  387. }
  388.  
  389. void loadpieces(flname)
  390. char *flname;
  391. {
  392.     register int jx, ix;
  393.     FILE *fl;
  394.     int res;
  395.  
  396.     fl = fopen(flname, "r");
  397.     if (fl==NULL) {
  398.     fprintf(stderr, "spatial: could not open shape file.\n");
  399.     exit(-1);
  400.     };
  401.  
  402.     res=fscanf(fl, "%hd\n", &numpieces);
  403.     if (res!=1) {
  404.     fprintf(stderr, "spatial: error 0 in shape file.\n");
  405.     exit(-1);
  406.     };
  407.  
  408.     for (ix=0; ix<numpieces; ix++) {
  409.     int in1, in2, in3;
  410.     res=fscanf(fl, "%d, %d, %d\n", &in1, &in2, &in3);
  411.     if (res!=3) {
  412.         fprintf(stderr, "spatial: error 1 in shape file.\n");
  413.         exit(-1);
  414.     };
  415.     pieces[ix].numcubes=in1;
  416.     pieces[ix].numverts=in2;
  417.     pieces[ix].numedges=in3;
  418.     pieces[ix].numpoints=in1+in2;
  419.     if (pieces[ix].numpoints>MAXPOINTS || pieces[ix].numedges>MAXEDGES) {
  420.         fprintf(stderr, "spatial: shape %d is too complex.\n", ix);
  421.         exit(-1);
  422.     };
  423.     for (jx=0; jx<pieces[ix].numpoints; jx++) {
  424.         point *p = &(pieces[ix].points[jx]);
  425.         res=fscanf(fl, "%lf, %lf, %lf\n",
  426.                &(p->x), &(p->y), &(p->z));
  427.         if (res!=3) {
  428.         fprintf(stderr, "spatial: error 2 in shape file.\n");
  429.         exit(-1);
  430.         };
  431.         p->w = 1.0;
  432.     };
  433.     pieces[ix].verts =
  434.       &(pieces[ix].points[pieces[ix].numcubes]);
  435.     for (jx=0; jx<pieces[ix].numedges; jx++) {
  436.         res=fscanf(fl, "%d,%d\n", &in1, &in2);
  437.         if (res!=2) {
  438.         fprintf(stderr, "spatial: error 3 in shape file.\n");
  439.         exit(-1);
  440.         };
  441.         pieces[ix].edges[jx].head = in1;
  442.         pieces[ix].edges[jx].tail = in2;
  443.     }
  444.     }
  445. }
  446.  
  447. void dumppiece(pnum)
  448. short pnum;
  449. {
  450.     piecelist *p = &(pieces[pnum]);
  451.     register int ix;
  452.  
  453.     printf("%d cubes, %d verts, %d edges\n",
  454.        p->numcubes, p->numverts, p->numedges);
  455.     for (ix=0; ix<p->numpoints; ix++) {
  456.     printf("%5.1f, %5.1f, %5.1f, %5.1f\n",
  457.            p->points[ix].x, p->points[ix].y,
  458.            p->points[ix].z, p->points[ix].w);
  459.     }
  460.     for (ix=0; ix<p->numedges; ix++) {
  461.     printf("%d,%d\n", p->edges[ix].head,
  462.            p->edges[ix].tail);
  463.     };
  464.     printf("\n");
  465. }
  466.